"""
标签页组件模块
提供了一个美观、可定制的标签页组件，用于组织内容
"""
from PyQt5.QtCore import Qt, QSize, QRect, QPoint, pyqtSignal
from PyQt5.QtGui import QPainter, QColor, QFont, QPen, QFontMetrics, QBrush, QIcon
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy,
                            QPushButton, QStackedWidget, QToolButton)

from component.theme import Theme


class TabButton(QToolButton):
    """标签按钮"""
    def __init__(self, text, parent=None, closable=True):
        super().__init__(parent)
        self.setText(text)
        self.setCheckable(True)
        self.setAutoRaise(True)  # 扁平化效果
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        
        # 设置最小宽度
        fm = QFontMetrics(self.font())
        text_width = fm.width(text)
        self.setMinimumWidth(text_width + 40)  # 文本宽度 + 边距
        
        # 是否可关闭
        self.closable = closable
        
        # 设置样式
        self._apply_style()
    
    def _apply_style(self):
        """应用样式"""
        self.setStyleSheet(f"""
            QToolButton {{
                border: none;
                border-bottom: 2px solid transparent;
                padding: 8px 12px;
                font-size: 14px;
                color: {Theme.TEXT_REGULAR};
                background: transparent;
            }}
            
            QToolButton:hover {{
                color: {Theme.PRIMARY};
            }}
            
            QToolButton:checked {{
                color: {Theme.PRIMARY};
                border-bottom: 2px solid {Theme.PRIMARY};
                font-weight: bold;
            }}
        """)


class TabCloseButton(QToolButton):
    """标签关闭按钮"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(16, 16)
        self.setAutoRaise(True)  # 扁平化效果
        
        # 设置样式
        self.setStyleSheet(f"""
            QToolButton {{
                border: none;
                border-radius: 8px;
                background: transparent;
                color: {Theme.TEXT_SECONDARY};
            }}
            
            QToolButton:hover {{
                background: rgba(0, 0, 0, 0.1);
                color: {Theme.DANGER};
            }}
        """)
        
        # 设置文本
        self.setText("×")
        self.setToolTip("关闭")


class Tabs(QWidget):
    """
    标签页组件
    
    提供了一个美观、可定制的标签页组件，用于组织内容
    
    参数:
        parent: 父组件
        tab_position: 标签位置，可选值为 "top"（顶部）或 "bottom"（底部）
        closable: 标签是否可关闭
        stretch_tabs: 标签是否拉伸填充整个宽度
        active_color: 激活状态的颜色
    
    信号:
        tab_changed(int): 当前标签页改变时发出，参数为标签页索引
        tab_closed(int): 标签页关闭时发出，参数为标签页索引
    """
    
    # 自定义信号
    tab_changed = pyqtSignal(int)
    tab_closed = pyqtSignal(int)
    
    def __init__(self, parent=None, tab_position="top", closable=True, 
                 stretch_tabs=False, active_color=None):
        super().__init__(parent)
        
        # 属性初始化
        self._tab_position = tab_position
        self._closable = closable
        self._stretch_tabs = stretch_tabs
        self._active_color = active_color or Theme.PRIMARY
        
        # 创建布局
        self._main_layout = QVBoxLayout(self)
        self._main_layout.setContentsMargins(0, 0, 0, 0)
        self._main_layout.setSpacing(0)
        
        # 创建标签栏
        self._tab_bar = QWidget()
        self._tab_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self._tab_bar.setMinimumHeight(40)
        
        # 标签栏布局
        self._tab_bar_layout = QHBoxLayout(self._tab_bar)
        self._tab_bar_layout.setContentsMargins(0, 0, 0, 0)
        self._tab_bar_layout.setSpacing(0)
        
        if self._stretch_tabs:
            self._tab_bar_layout.addStretch(1)
        
        # 创建内容区域
        self._content_area = QStackedWidget()
        self._content_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        
        # 根据标签位置添加组件
        if self._tab_position == "top":
            self._main_layout.addWidget(self._tab_bar)
            self._main_layout.addWidget(self._content_area)
        else:
            self._main_layout.addWidget(self._content_area)
            self._main_layout.addWidget(self._tab_bar)
        
        # 标签按钮列表
        self._tab_buttons = []
        self._close_buttons = []
        
        # 设置样式
        self._apply_style()
    
    def _apply_style(self):
        """应用样式"""
        # 标签栏样式
        self._tab_bar.setStyleSheet(f"""
            background-color: {Theme.BG_COLOR};
            border-bottom: 1px solid {Theme.BORDER_BASE};
        """)
        
        # 内容区域样式
        self._content_area.setStyleSheet(f"""
            background-color: {Theme.BG_COLOR};
            border: 1px solid {Theme.BORDER_BASE};
            border-top: none;
        """)
        
        # 如果标签在底部，调整边框
        if self._tab_position == "bottom":
            self._tab_bar.setStyleSheet(f"""
                background-color: {Theme.BG_COLOR};
                border-top: 1px solid {Theme.BORDER_BASE};
            """)
            
            self._content_area.setStyleSheet(f"""
                background-color: {Theme.BG_COLOR};
                border: 1px solid {Theme.BORDER_BASE};
                border-bottom: none;
            """)
    
    def add_tab(self, title, widget, closable=None):
        """
        添加标签页
        
        参数:
            title: 标签标题
            widget: 标签内容组件
            closable: 是否可关闭，如果为None则使用全局设置
        
        返回:
            标签页索引
        """
        # 获取当前索引
        current_index = len(self._tab_buttons)
        
        # 创建标签按钮
        tab_button = TabButton(title, self._tab_bar, closable if closable is not None else self._closable)
        # 使用固定的索引值，而不是动态计算
        tab_button.clicked.connect(lambda checked, idx=current_index: self._on_tab_clicked(idx))
        
        # 创建标签布局
        tab_layout = QHBoxLayout()
        tab_layout.setContentsMargins(0, 0, 0, 0)
        tab_layout.setSpacing(2)
        tab_layout.addWidget(tab_button)
        
        # 如果可关闭，添加关闭按钮
        close_button = None
        if tab_button.closable:
            close_button = TabCloseButton(self._tab_bar)
            # 使用固定的索引值，而不是动态计算
            close_button.clicked.connect(lambda checked, idx=current_index: self._on_tab_close(idx))
            tab_layout.addWidget(close_button)
        
        # 创建标签容器
        tab_container = QWidget()
        tab_container.setLayout(tab_layout)
        
        # 添加到标签栏
        if self._stretch_tabs:
            self._tab_bar_layout.insertWidget(self._tab_bar_layout.count() - 1, tab_container, 1)
        else:
            self._tab_bar_layout.addWidget(tab_container)
        
        # 添加到内容区域
        self._content_area.addWidget(widget)
        
        # 添加到按钮列表
        self._tab_buttons.append(tab_button)
        self._close_buttons.append(close_button)
        
        # 如果是第一个标签，设置为当前标签
        if len(self._tab_buttons) == 1:
            tab_button.setChecked(True)
            self._content_area.setCurrentIndex(0)
        
        # 返回标签索引
        return current_index
    
    def _on_tab_clicked(self, index):
        """标签点击事件"""
        # 取消其他标签的选中状态
        for i, button in enumerate(self._tab_buttons):
            if i != index:
                button.setChecked(False)
        
        # 设置当前标签为选中状态
        self._tab_buttons[index].setChecked(True)
        
        # 切换内容区域
        self._content_area.setCurrentIndex(index)
        
        # 发出信号
        self.tab_changed.emit(index)
    
    def _on_tab_close(self, index):
        """标签关闭事件"""
        # 移除标签
        self.remove_tab(index)
        
        # 发出信号
        self.tab_closed.emit(index)
    
    def remove_tab(self, index):
        """
        移除标签页
        
        参数:
            index: 标签页索引
        """
        if 0 <= index < len(self._tab_buttons):
            # 获取标签容器
            tab_container = self._tab_buttons[index].parent()
            
            # 从布局中移除
            self._tab_bar_layout.removeWidget(tab_container)
            
            # 从内容区域移除
            widget = self._content_area.widget(index)
            self._content_area.removeWidget(widget)
            
            # 从按钮列表移除
            self._tab_buttons.pop(index)
            self._close_buttons.pop(index)
            
            # 删除组件
            tab_container.deleteLater()
            widget.deleteLater()
            
            # 如果还有标签，选中第一个
            if self._tab_buttons:
                # 如果关闭的是当前标签，选中第一个标签
                if index == self._content_area.currentIndex():
                    new_index = min(index, len(self._tab_buttons) - 1)
                    self._tab_buttons[new_index].setChecked(True)
                    self._content_area.setCurrentIndex(new_index)
                    self.tab_changed.emit(new_index)
                # 如果关闭的标签在当前标签之前，需要调整当前标签索引
                elif index < self._content_area.currentIndex():
                    self._content_area.setCurrentIndex(self._content_area.currentIndex() - 1)
    
    def set_current_index(self, index):
        """
        设置当前标签页
        
        参数:
            index: 标签页索引
        """
        if 0 <= index < len(self._tab_buttons):
            self._on_tab_clicked(index)
    
    def get_current_index(self):
        """
        获取当前标签页索引
        
        返回:
            当前标签页索引
        """
        return self._content_area.currentIndex()
    
    def get_count(self):
        """
        获取标签页数量
        
        返回:
            标签页数量
        """
        return len(self._tab_buttons)
    
    def set_tab_text(self, index, text):
        """
        设置标签页文本
        
        参数:
            index: 标签页索引
            text: 标签页文本
        """
        if 0 <= index < len(self._tab_buttons):
            self._tab_buttons[index].setText(text)
    
    def get_tab_text(self, index):
        """
        获取标签页文本
        
        参数:
            index: 标签页索引
        
        返回:
            标签页文本
        """
        if 0 <= index < len(self._tab_buttons):
            return self._tab_buttons[index].text()
        return ""
    
    def set_tab_closable(self, index, closable):
        """
        设置标签页是否可关闭
        
        参数:
            index: 标签页索引
            closable: 是否可关闭
        """
        if 0 <= index < len(self._tab_buttons):
            # 获取标签容器
            tab_container = self._tab_buttons[index].parent()
            tab_layout = tab_container.layout()
            
            # 设置标签按钮是否可关闭
            self._tab_buttons[index].closable = closable
            
            # 如果已经有关闭按钮
            if self._close_buttons[index]:
                if not closable:
                    # 移除关闭按钮
                    tab_layout.removeWidget(self._close_buttons[index])
                    self._close_buttons[index].deleteLater()
                    self._close_buttons[index] = None
            else:
                if closable:
                    # 添加关闭按钮
                    close_button = TabCloseButton(self._tab_bar)
                    # 使用固定的索引值
                    close_button.clicked.connect(lambda checked, idx=index: self._on_tab_close(idx))
                    tab_layout.addWidget(close_button)
                    self._close_buttons[index] = close_button
    
    def set_tab_position(self, position):
        """
        设置标签位置
        
        参数:
            position: 标签位置，可选值为 "top"（顶部）或 "bottom"（底部）
        """
        if position in ["top", "bottom"] and position != self._tab_position:
            self._tab_position = position
            
            # 从布局中移除组件
            self._main_layout.removeWidget(self._tab_bar)
            self._main_layout.removeWidget(self._content_area)
            
            # 根据标签位置重新添加组件
            if self._tab_position == "top":
                self._main_layout.addWidget(self._tab_bar)
                self._main_layout.addWidget(self._content_area)
            else:
                self._main_layout.addWidget(self._content_area)
                self._main_layout.addWidget(self._tab_bar)
            
            # 更新样式
            self._apply_style()
    
    def set_stretch_tabs(self, stretch):
        """
        设置标签是否拉伸填充整个宽度
        
        参数:
            stretch: 是否拉伸
        """
        if stretch != self._stretch_tabs:
            self._stretch_tabs = stretch
            
            # 清除布局中的所有组件
            while self._tab_bar_layout.count():
                item = self._tab_bar_layout.takeAt(0)
                if item.widget():
                    self._tab_bar_layout.removeWidget(item.widget())
            
            # 重新添加标签
            if self._stretch_tabs:
                for i, button in enumerate(self._tab_buttons):
                    tab_container = button.parent()
                    self._tab_bar_layout.addWidget(tab_container, 1)  # 1表示拉伸因子
                self._tab_bar_layout.addStretch(1)
            else:
                for i, button in enumerate(self._tab_buttons):
                    tab_container = button.parent()
                    self._tab_bar_layout.addWidget(tab_container)
    
    def set_active_color(self, color):
        """
        设置激活状态的颜色
        
        参数:
            color: 颜色值
        """
        self._active_color = color
        
        # 更新标签按钮样式
        for button in self._tab_buttons:
            button.setStyleSheet(f"""
                QToolButton {{
                    border: none;
                    border-bottom: 2px solid transparent;
                    padding: 8px 12px;
                    font-size: 14px;
                    color: {Theme.TEXT_REGULAR};
                    background: transparent;
                }}
                
                QToolButton:hover {{
                    color: {self._active_color};
                }}
                
                QToolButton:checked {{
                    color: {self._active_color};
                    border-bottom: 2px solid {self._active_color};
                    font-weight: bold;
                }}
            """) 